﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Spinning.Spinning.Unitity;
using Microsoft.Xna.Framework;
using Microsoft.Devices.Sensors;
using System.Net;

namespace Spinning.Spinning.Entity.Scenes
{
    class ClientScene : PracticeScene
    {
        Vector3 _accelReading = new Vector3();
        //Player Enemy;
        AnimationSprite PlayerSprite,EnemySprite;
        private UdpAnySourceMulticastChannel Channel { get; set; }
        TextEntity te;

        public ClientScene()
            : base()
        {
            //Game1._acceleMeter.ReadingChanged += GSensorChanged;
            Game1._acceleMeter.CurrentValueChanged += GSensorChanged;
            try
            {
                Game1._acceleMeter.Start();
            }
            catch (AccelerometerFailedException e) { throw e; }
            catch (UnauthorizedAccessException e) { throw e; }
        }

        void GSensorChanged(object sender, SensorReadingEventArgs<AccelerometerReading> e)
        {
            _accelReading.X = (float)e.SensorReading.Acceleration.X;
            _accelReading.Y = -(float)e.SensorReading.Acceleration.Y;
            _accelReading.Z = (float)e.SensorReading.Acceleration.Z;    
        }

        public override void OnLoad()
        {
            base.OnLoad();
            //Enemy = new Player();
            //Enemy.textureName = "spinning";
            //Enemy.OnLoad();
            //Enemy.SetAnimation(Constants.playerAnimationFrame);
            //Enemy.OnCreatBody(World, PhysicConnectManager);
            //Enemy.BodyPosiotion = new Vector2(240, 200);
            //this.Attach(Enemy);
            Player.Alpha = 0;//player藏起來

            PlayerSprite = new AnimationSprite();
            PlayerSprite.textureName = "spinning";
            PlayerSprite.OnLoad();
            PlayerSprite.SetAnimation(Constants.playerAnimationFrame);
            PlayerSprite.SetChangeFrameAnimation(new int[] { 2, 3 });
            PlayerSprite.ZIndex = Constants.player;
            this.Attach(PlayerSprite);

            EnemySprite = new AnimationSprite();
            EnemySprite.textureName = "spinning";
            EnemySprite.OnLoad();
            EnemySprite.SetAnimation(Constants.playerAnimationFrame);
            EnemySprite.SetChangeFrameAnimation(new int[] { 2, 3 });
            EnemySprite.ZIndex = Constants.enemy;
            this.Attach(EnemySprite);

            te = new TextEntity();
            ResourceManager.ContentRoot = "";
            te.fontString = "TestFont";
            te.OnLoad();
            te.Origin = new Vector2(0.5f);
            te.Position = new Vector2(200, 200);
            te.Color = Color.Blue;
            //te.Alpha = 0;
            te.ZIndex = Constants.debugText;
            Attach(te);
            te.Value = "client";
            this.Channel = new UdpAnySourceMulticastChannel(IPAddress.Parse("224.0.1.100"), 3000);
            this.Channel.AfterOpen += new EventHandler(Channel_AfterOpen);
            this.Channel.BeforeClose += new EventHandler(Channel_BeforeClose);
            this.Channel.PacketReceived += new EventHandler<UdpPacketReceivedEventArgs>(Channel_PacketReceived);

            this.Channel.Open();
        }

        void Channel_BeforeClose(object sender, EventArgs e)
        {
            this.Channel.Send("END,{0}, leaves the UDP Multicast chat,", Game1.clientId);
        }

        void Channel_AfterOpen(object sender, EventArgs e)
        {
            this.Channel.Send("BEGIN,{0}, enters the UDP Multicast chat,", Game1.clientId);
        }

        //沒用到Channel.close(); 範例也沒

        void Channel_PacketReceived(object sender, UdpPacketReceivedEventArgs e)
        {
            string[] temp;
            string[] temp1;

            temp = e.Message.Split(',');

            NoKeyFoundDictionary dataDictionary = new NoKeyFoundDictionary();

            bool partyFlag = false;

            for (int i = 0; i < temp.Length; i++)
            {
                temp1 = temp[i].Split(':');
                if (temp1.Length >= 2)
                    dataDictionary.Add(temp1[0], temp1[1]);
            }

            if (dataDictionary.Get("hostId") == Game1.hostId && dataDictionary.Get("clientId") == Game1.clientId && dataDictionary.Get("isHost") == "True") //host 來的封包
            {
                partyFlag = true;
            }
            else
            {
                partyFlag = false;
            }

            if (partyFlag)
            {
                PlayerSprite.Position = new Vector2(float.Parse(dataDictionary.Get("enemyPosX")) - PlayerSprite._frameSize.X / 2, float.Parse(dataDictionary.Get("enemyPosY")) - PlayerSprite._frameSize.Y / 2);
                EnemySprite.Position = new Vector2(float.Parse(dataDictionary.Get("playerPosX")) - EnemySprite._frameSize.X / 2, float.Parse(dataDictionary.Get("playerPosY")) - EnemySprite._frameSize.Y / 2);
                tempCounter++;
                te.Value = "ClientCounter:" + tempCounter;
            
            }
        }

        int tempTimer = 0;
        Vector3 preAcc;
        int tempCounter;
        protected override void UpdateSelf(GameTime gameTime)
        {
            base.UpdateSelf(gameTime);
            int delta = gameTime.ElapsedGameTime.Milliseconds;
            tempTimer += delta;
            if (tempTimer / 50 >= 1)
            {
            //    tempTimer = tempTimer % 50;

            if (checkDif(_accelReading,preAcc,0.05f))
                this.Channel.Send("hostId:{0},clientId:{1},accX:{2},accY:{3},accZ:{4},isHost:False,", Game1.hostId, Game1.clientId, _accelReading.X, _accelReading.Y, _accelReading.Z);
                preAcc = _accelReading;
            
            //    //this.Channel.Send("{0},{1},{2},{3},", Game1.hostId, _accelReading.X, _accelReading.Y, _accelReading.Z);
            }
            
        }

        bool checkDif(Vector3 a, Vector3 b, float diff) 
        {
            if (Math.Abs(a.X - b.X) > diff || Math.Abs(a.Y - b.Y) > diff)
                return true;
            else
                return false;
        }

        public override Scene Clone()
        {
            Scene scene = new ClientScene();
            scene.Size = new Vector2(Constants.Window_Width, Constants.Window_Height);
            scene.OnLoad();
            scene.SortChildren();
            return scene;
        }
    }
}

